package com.kexio.security.domain;

import java.util.List;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.kexio.core.data.domain.BaseEntity;
import com.kexio.security.domain.enums.PermissionStatus;
import com.kexio.security.domain.enums.PermissionType;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 权限实体
 * 
 * @author Kexio Team
 * @since 1.0.0
 */
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_permission")
@Schema(description = "权限实体")
public class Permission extends BaseEntity {

    /**
     * 权限编码
     */
    @NotBlank(message = "权限编码不能为空")
    @Size(min = 2, max = 100, message = "权限编码长度必须在2-100之间")
    @Pattern(regexp = "^[a-zA-Z0-9:_.-]+$", message = "权限编码只能包含字母、数字、冒号、下划线、点和横线")
    @TableField("permission_code")
    @Schema(description = "权限编码", example = "system:user:create")
    private String permissionCode;

    /**
     * 权限名称
     */
    @NotBlank(message = "权限名称不能为空")
    @Size(min = 2, max = 50, message = "权限名称长度必须在2-50之间")
    @TableField("permission_name")
    @Schema(description = "权限名称", example = "创建用户")
    private String permissionName;

    /**
     * 权限类型
     */
    @TableField("permission_type")
    @Schema(description = "权限类型", example = "1")
    private Integer permissionType;

    /**
     * 父权限ID
     */
    @TableField("parent_id")
    @Schema(description = "父权限ID", example = "1")
    private Long parentId;

    /**
     * 权限路径
     */
    @Size(max = 200, message = "权限路径长度不能超过200")
    @TableField("path")
    @Schema(description = "权限路径", example = "/system/user")
    private String path;

    /**
     * 组件路径
     */
    @Size(max = 255, message = "组件路径长度不能超过255")
    @TableField("component")
    @Schema(description = "组件路径", example = "system/user/index")
    private String component;

    /**
     * 权限图标
     */
    @Size(max = 100, message = "权限图标长度不能超过100")
    @TableField("icon")
    @Schema(description = "权限图标", example = "user")
    private String icon;

    /**
     * 显示顺序
     */
    @TableField("sort_order")
    @Schema(description = "显示顺序", example = "1")
    private Integer sortOrder;

    /**
     * 权限状态
     */
    @TableField("status")
    @Schema(description = "权限状态", example = "1")
    private Integer status;

    /**
     * 是否为外部链接
     */
    @TableField("is_external")
    @Schema(description = "是否为外部链接", example = "false")
    private Boolean isExternal;

    /**
     * 是否缓存
     */
    @TableField("is_cached")
    @Schema(description = "是否缓存", example = "true")
    private Boolean isCached;

    /**
     * 是否显示
     */
    @TableField("is_visible")
    @Schema(description = "是否显示", example = "true")
    private Boolean isVisible;

    /**
     * 权限描述
     */
    @Size(max = 500, message = "权限描述长度不能超过500")
    @TableField("description")
    @Schema(description = "权限描述", example = "用户管理权限")
    private String description;

    /**
     * 租户ID
     */
    @TableField("tenant_id")
    @Schema(description = "租户ID", example = "1")
    private Long tenantId;

    /**
     * 备注
     */
    @Size(max = 500, message = "备注长度不能超过500")
    @TableField("remark")
    @Schema(description = "备注", example = "系统内置权限")
    private String remark;

    /**
     * 子权限列表（非数据库字段）
     */
    @TableField(exist = false)
    private List<Permission> children;

    // =========================== 便利方法 ===========================

    /**
     * 获取权限类型枚举
     * @return 权限类型枚举
     */
    public PermissionType getPermissionType() {
        return PermissionType.fromCode(this.permissionType);
    }

    /**
     * 设置权限类型
     * @param permissionType 权限类型枚举
     */
    public void setPermissionType(PermissionType permissionType) {
        this.permissionType = permissionType != null ? permissionType.getCode() : null;
    }

    /**
     * 获取权限状态枚举
     * @return 权限状态枚举
     */
    public PermissionStatus getPermissionStatus() {
        return PermissionStatus.fromCode(this.status);
    }

    /**
     * 设置权限状态
     * @param permissionStatus 权限状态枚举
     */
    public void setPermissionStatus(PermissionStatus permissionStatus) {
        this.status = permissionStatus != null ? permissionStatus.getCode() : null;
    }

    /**
     * 检查权限是否启用
     * @return 是否启用
     */
    public boolean isEnabled() {
        PermissionStatus permissionStatus = getPermissionStatus();
        return permissionStatus != null && permissionStatus.isEnabled();
    }

    /**
     * 检查权限是否禁用
     * @return 是否禁用
     */
    public boolean isDisabled() {
        PermissionStatus permissionStatus = getPermissionStatus();
        return permissionStatus != null && permissionStatus.isDisabled();
    }

    /**
     * 检查是否为菜单权限
     * @return 是否菜单权限
     */
    public boolean isMenuPermission() {
        PermissionType type = getPermissionType();
        return type != null && type.isMenu();
    }

    /**
     * 检查是否为按钮权限
     * @return 是否按钮权限
     */
    public boolean isButtonPermission() {
        PermissionType type = getPermissionType();
        return type != null && type.isButton();
    }

    /**
     * 检查是否为API权限
     * @return 是否API权限
     */
    public boolean isApiPermission() {
        PermissionType type = getPermissionType();
        return type != null && type.isApi();
    }

    /**
     * 检查是否为顶级权限
     * @return 是否顶级权限
     */
    public boolean isRootPermission() {
        return this.parentId == null || this.parentId == 0;
    }

    /**
     * 检查权限是否可用
     * @return 是否可用
     */
    public boolean isUsable() {
        PermissionStatus permissionStatus = getPermissionStatus();
        return permissionStatus != null && permissionStatus.isUsable();
    }

    // ==================== 手写Getter/Setter方法（补充缺失的） ====================
    
    // 只添加缺失的getter/setter方法，避免与现有方法冲突
    public String getPermissionCode() { return permissionCode; }
    public String getPermissionName() { return permissionName; }
    public Integer getStatus() { return status; }
    public String getPath() { return path; }
    public String getComponent() { return component; }
    public String getIcon() { return icon; }
    public Integer getSortOrder() { return sortOrder; }
    public Long getParentId() { return parentId; }
    public Boolean getIsExternal() { return isExternal; }
    public Boolean getIsCached() { return isCached; }
    public Boolean getIsVisible() { return isVisible; }
    public String getDescription() { return description; }
    public Long getTenantId() { return tenantId; }
    public String getRemark() { return remark; }
    public List<Permission> getChildren() { return children; }
    
    public void setPermissionCode(String permissionCode) { this.permissionCode = permissionCode; }
    public void setPermissionName(String permissionName) { this.permissionName = permissionName; }
    public void setStatus(Integer status) { this.status = status; }
    public void setPath(String path) { this.path = path; }
    public void setComponent(String component) { this.component = component; }
    public void setIcon(String icon) { this.icon = icon; }
    public void setSortOrder(Integer sortOrder) { this.sortOrder = sortOrder; }
    public void setParentId(Long parentId) { this.parentId = parentId; }
    public void setIsExternal(Boolean isExternal) { this.isExternal = isExternal; }
    public void setIsCached(Boolean isCached) { this.isCached = isCached; }
    public void setIsVisible(Boolean isVisible) { this.isVisible = isVisible; }
    public void setDescription(String description) { this.description = description; }
    public void setTenantId(Long tenantId) { this.tenantId = tenantId; }
    public void setRemark(String remark) { this.remark = remark; }
    public void setChildren(List<Permission> children) { this.children = children; }
}
